﻿#ifndef IIDATABASE_H
#define IIDATABASE_H

#include <QSqlDatabase>
#include <QObject>
#include <QDateTime>
#include <QApplication>
#include <QDataStream>
#include <QTimer>
#include <QUuid>

#define DBDateTimeFormat "yyyy_MM_dd_hh_mm_ss_zzz"
#define DBUuid "uuid"
#define DBCreatTime "creatTime"
#define DBModifyTime "modifyTime"
#define DBJson "json"
#define KeyData "data"


struct SqlLinkParam{
    QString linkName;
    QString sqlType;
    QString ip;
    int port;
    QString user;
    QString password;
    QString dbName;
    QString tableName;
    SqlLinkParam():linkName("link0"),sqlType("QSQLITE"), ip("127.0.0.1"), port(3306), user("root"), password("root"),
        dbName(QApplication::applicationName() + "Data"), tableName(QApplication::applicationName() + "Table"){}
    SqlLinkParam(QString linkName, QString sqlType, QString ip, int port, QString user, QString password, QString dbName, QString tableName){
        this->linkName = linkName;
        this->sqlType = sqlType;
        this->ip = ip;
        this->port = port;
        this->user = user;
        this->password = password;
        this->dbName = dbName;
        this->tableName = tableName;
    }
    ~SqlLinkParam()
    {
    }
    friend QDataStream &operator << (QDataStream &out, const SqlLinkParam &config)
    {
        out << config.linkName
            << config.sqlType
            << config.ip
            << config.port
            << config.user
            << config.password
            << config.dbName
            << config.tableName;
        return out;
    }
    friend QDataStream &operator>>(QDataStream &in, SqlLinkParam &config)
    {
        in >> config.linkName
            >> config.sqlType
            >> config.ip
            >> config.port
            >> config.user
            >> config.password
            >> config.dbName
            >> config.tableName;
        return in;
    }
};
Q_DECLARE_METATYPE(SqlLinkParam)
enum SqlState{
    SS_Invalid = 0,
    SS_Valid,
};
Q_DECLARE_METATYPE(SqlState)

enum SqlError{
    SE_No,
    SE_NoServer,
    SE_Unconnect,
    SE_CreateDB,
    SE_CreateTB,
    SE_Insert,
    SE_Select,
    SE_Update,
    SE_Delete,
};
Q_DECLARE_METATYPE(SqlError)

class IDatabase : public QObject
{
    Q_OBJECT
public:
    IDatabase(QObject *parent = nullptr);
    IDatabase(const SqlLinkParam& par, QObject *parent = nullptr);
    virtual ~IDatabase();
    void setSqlLinkParam(const SqlLinkParam& par){mLinkPar = par;}
    void setSqlError(SqlError err);
    SqlState getSqlState(){return mState;}
    SqlError getSqlErr(){return mErr;}
    QString getErrMsg(){return mErrMsg;}
    QString getUuid();
    void checkErrType(QSqlQuery query);

public:
    virtual bool init() = 0;
    virtual void setSqlState(SqlState state);
    //向某个数据表中插入一条数据
    virtual bool createRow(const QJsonObject& jsonObject);

    //删除某个数据表中的一条数据
    virtual bool deleteRowByDateTime(const QDateTime& dateTimeBegin, const QDateTime& dateTimeEnd);

    virtual bool deleteRowByUuid(const QString& uuid);

    //查找数据库中的数据
    virtual bool findRowsByData(const QString& searchText, QJsonArray& datas);

    virtual bool findRowsByDateTime(const QDateTime& dateTimeBegin, const QDateTime& dateTimeEnd, QJsonArray& datas);

    //根据一条ID查找数据
    virtual bool findRowByDateTime(const QDateTime& dateTime, QJsonObject& jsonData);

    virtual bool findRowByUuid(const QString& uuid, QJsonObject& jsonData);

    //查找所有数据
    virtual bool readAllRows(QJsonArray& datas);

    //更新某条数据内容
    virtual bool updateRow(const QJsonObject& jsonObject);

protected:
    QSqlDatabase mDb;
    SqlLinkParam mLinkPar;
    SqlState mState = SS_Invalid;
    SqlError mErr = SE_No;
    QString mErrMsg = "";

};

#endif // IIDATABASE_H
